package com.tepth.appmanageservice.tools.ext;

import com.tepth.appmanageservice.protocol.Index;
import com.tepth.appmanageservice.protocol.interfaces.IReceive;
import com.tepth.appmanageservice.protocol.interfaces.ISend;
import com.tepth.appmanageservice.protocol.packets.Check;
import com.tepth.appmanageservice.protocol.packets.Header;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class ExtToBytes {
	public static byte fromStringBit(String bitStr) {
		byte result = 0;
		for (int i = bitStr.length() - 1, j = 0; i >= 0; i--, j++) {
			result += (Byte.parseByte(bitStr.charAt(i) + "") * Math.pow(2, j));
		}
		return result;
	}

	public static byte[] fromString16(String str) {
		str = str.replace(" ", "");
		char[] chars = str.toCharArray();

		byte[] ss = new byte[chars.length / 2];
		for (int i = 0, j = 0; i < chars.length;) {
			ss[j++] = (byte) Integer.parseInt(new String(new char[] { chars[i++], chars[i++] }), 16);
		}

		return ss;
	}

	public static byte[] fromString16(String str, String s) {
		String[] strs = str.split(s);
		byte[] ss = new byte[strs.length];

		for (int i = 0; i < strs.length; i++) {
			ss[i] = (byte) Integer.parseInt(strs[i], 16);
		}

		return ss;
	}

	public static byte[] fromStringHex(String s) {
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			try {
				baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return baKeyword;
	}

	public static byte[] fromStringForCoding(String value) {
		if (null == value)
			value = "";

		return value.getBytes();
	}

	public static byte[] fromStringBytes(String s) {
		int index = 0;
		int tLength = s.length();
		int slength = tLength % 8;
		int g = slength == 0 ? tLength / 8 : tLength / 8 + 1;

		byte[] datas = new byte[g + 1];
		int i = 0;
		datas[i++] = (byte) g;
		while (index < tLength) {
			int slen = tLength - index;
			int qlen = 8;
			if (slen <= 8) {
				qlen = slen;
			}

			datas[i++] = (byte) Short.parseShort(ExtToString.reverse(s.substring(index, index + qlen)), 2);
			index += qlen;
		}

		return datas;
	}

	public static byte[] fromByteArray2(byte[][] datas) {
		int length = datas.length;
		int len = 0;

		for (int i = 0; i < length; i++) {
			len += datas[i].length;
		}
		byte[] data = new byte[len];
		int index = 0;
		for (int i = 0; i < length; i++) {
			byte[] d = datas[i];
			for (int j = 0; j < d.length; j++) {
				data[index++] = d[j];
			}
		}
		return data;
	}

	public static byte[] fromByteArrayList(ArrayList<Byte> list) {
		int length = list.size();
		byte[] datas = new byte[length];
		for (int i = 0; i < length; i++) {
			datas[i] = list.get(i);
		}
		return datas;
	}

	public static byte[] fromByteList(List<Byte> list) {
		int length = list.size();
		byte[] data = new byte[length];
		for (int i = 0; i < length; i++) {
			data[i] = list.get(i);
		}
		return data;
	}

	public static byte[] fromByteArray(byte[] data, Index index, int len) {
		byte[] newdata = new byte[len];
		for (int i = 0; i < len; i++) {
			newdata[i] = data[index.get()];
		}
		return newdata;
	}

	public static byte[] fromNumber(byte data) {
		return new byte[] { data };
	}

	public static byte[] fromNumber(short data) {
		byte[] bLocalArr = new byte[2];
		for (int i = 0; (i < 4) && (i < 2); i++) {
			bLocalArr[i] = (byte) (data >> 8 * i & 0xFF);
		}
		return bLocalArr;
	}

	public static byte[] fromNumber(int data) {
		byte[] bLocalArr = new byte[4];
		for (int i = 0; (i < 4) && (i < 4); i++) {
			bLocalArr[i] = (byte) (data >> 8 * i & 0xFF);
		}
		return bLocalArr;
	}

	public static byte[] fromDateLong(Date dateTime) {
		SimpleDateFormat formatter2 = new SimpleDateFormat("yy MM dd HH mm ss SSSS", Locale.getDefault());
		String hms = formatter2.format(dateTime);
		String date16 = hms.substring(0, 20) + " " + hms.substring(20);

		return fromString16(date16, " ");
	}

	public static byte[] fromDateShort(Date dateTime) {
		SimpleDateFormat formatter2 = new SimpleDateFormat("yy MM dd HH mm ss", Locale.getDefault());
		String hms = formatter2.format(dateTime);
		String date16 = hms.substring(0, 16) + hms.substring(16);

		return fromString16(date16, " ");
	}

	public static byte[] generatePacketsData(ISend begin, Header header, ISend body, Check check, ISend end) {
		begin.load();
		body.load();
		header.setBodyLength(body.getLength());
		header.setId(body.getId());
		header.load();
		byte[] bodyBytes = body.getResult();

		byte[] aesKeys = ExtPro.getClient().getAES_KEYS();
		if (aesKeys != null) {
			try {
				bodyBytes = ExtPro.encrypt(aesKeys, bodyBytes);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		check.load(header.getResult(), bodyBytes);
		end.load();

		byte[] data = new byte[begin.getLength() + header.getLength() + bodyBytes.length + check.getLength() + end.getLength()];

		Index index = new Index();
		setDataBytes(data, begin.getResult(), index);
		setDataBytes(data, header.getResult(), index);
		setDataBytes(data, bodyBytes, index);
		setDataBytes(data, check.getResult(), index);
		setDataBytes(data, end.getResult(), index);

		return data;
	}

	public static byte[] generatePacketsBodyData(byte[] data, Index index, IReceive flag, Header header, Check check, IReceive end) {
		flag.Receive(data, index);
		header.Receive(data, index);

		byte[] body = new byte[header.getBodyLength()];

		for (int i = 0; i < body.length; i++) {
			body[i] = data[index.get()];
		}
		check.Receive(data, index);
		end.Receive(data, index);

		check.check(data);

		return body;
	}

	private static void setDataBytes(byte[] data, byte[] result, Index index) {
		for (int i = 0; i < result.length; i++) {
			data[index.get()] = result[i];
		}
	}
}